package com.xc.quickstart.service.impl;


import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xc.quickstart.admin.query.CrmConfigQuery;
import com.xc.quickstart.common.constant.ConfigKeyConstant;
import com.xc.quickstart.common.constant.ConfigTypeConstant;
import com.xc.quickstart.common.constant.RedisKeyConstant;
import com.xc.quickstart.common.context.ApiContext;
import com.xc.quickstart.common.model.ApiResponse;
import com.xc.quickstart.infrastructure.redis.RedisService;
import com.xc.quickstart.mapper.CrmConfigMapper;
import com.xc.quickstart.mapper.entity.CrmConfigENT;
import com.xc.quickstart.service.CrmConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 通用配置
 *
 * @author xc
 * @since 2021-04-20 11:47:08
 **/

@Slf4j
@Component("crmConfigService")
public class CrmConfigServiceImpl implements CrmConfigService {

    @Autowired
    private CrmConfigMapper crmConfigMapper;
    @Autowired
    private RedisService redisService;

    /**
     * 区域半径，单位m
     */
    private static final Integer DEFAULT_RADIUS_LIMIT = 200;

    @Override
    public String getCurrentValue(String key, String type) {
        CrmConfigENT currentENT = getCurrentENT(key, type);

        if (null == currentENT) {
            return Strings.EMPTY;
        }

        return currentENT.getConfigValue();
    }

    @Override
    public CrmConfigENT getCurrentENT(String key, String type) {
        String redisKey = String.format(RedisKeyConstant.CONFIG_KEY, key, type);
        String redisValue = redisService.get(redisKey);

        if (StringUtils.isNotBlank(redisValue)) {
            return JSON.parseObject(redisValue, CrmConfigENT.class);
        }

        CrmConfigENT crmConfigENT = crmConfigMapper.get(key, type);
        if (null == crmConfigENT) {
            return null;
        }

        redisService.setex(redisKey, JSON.toJSONString(crmConfigENT), 1L, TimeUnit.DAYS);
        return crmConfigENT;
    }

    @Override
    public <T> T getCurrentENT(String key, String type, Class<T> clazz) {
        CrmConfigENT currentENT = getCurrentENT(key, type);
        if (null == currentENT) {
            return null;
        }

        return JSON.parseObject(currentENT.getConfigValue(), clazz);
    }


    @Override
    public <T> List<T> getCurrentENTList(String key, String type, Class<T> clazz) {
        CrmConfigENT currentENT = getCurrentENT(key, type);
        if (Objects.isNull(currentENT) || StringUtils.isEmpty(currentENT.getConfigValue())) {
            return Collections.emptyList();
        }

        JSONArray objects = JSON.parseArray(currentENT.getConfigValue());
        return objects.toJavaList(clazz);
    }

    @Override
    public Integer getTestFlag(String name) {
        try {
            if (StringUtils.isEmpty(name)) {
                return 0;
            }
            //查询测试数据类型
            List<String> nameList = getCurrentENTList(ConfigKeyConstant.TEST_DATA_TYPE, ConfigTypeConstant.CRM, String.class);

            if (CollectionUtils.isEmpty(nameList)) {
                return 0;
            }

            return nameList.stream().anyMatch(r -> r.contains(name)) ? 1 : 0;
        } catch (Exception ex) {
            log.error("[getTestFlag异常],ex:{},key:{},type:{},crmTraceId:{}", ExceptionUtil.stacktraceToString(ex), "test_data_type", "crm", ApiContext.getCrmTraceId());
        }

        return 0;
    }


    @Override
    public List<CrmConfigENT> listCurrentENT(String type) {
        String redisKey = String.format(RedisKeyConstant.CONFIG_LIST_KEY, type);
        String redisValue = redisService.get(redisKey);
        if (StringUtils.isNotBlank(redisValue)) {
            return JSON.parseArray(redisValue, CrmConfigENT.class);
        }
        List<CrmConfigENT> crmConfigENTList = crmConfigMapper.list(type);
        if (CollectionUtils.isEmpty(crmConfigENTList)) {
            return Collections.emptyList();
        }
        redisService.setex(redisKey, JSON.toJSONString(crmConfigENTList), 1L, TimeUnit.SECONDS);
        return crmConfigENTList;
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public ApiResponse selectPage(CrmConfigQuery query) {
        LambdaQueryWrapper<CrmConfigENT> pageWrapper = Wrappers.lambdaQuery();
        IPage<CrmConfigENT> page = crmConfigMapper.selectPage(new Page<>(query.getPageNumber(), query.getPageSize()), pageWrapper);
        return ApiResponse.ok(page);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResponse save(CrmConfigENT entity) {
        int insert = crmConfigMapper.insert(entity);
        if (insert <= 0) {
            return ApiResponse.FAIL;
        }
        return ApiResponse.OK;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResponse update(CrmConfigENT entity) {
        int update = crmConfigMapper.updateById(entity);
        if (update <= 0) {
            return ApiResponse.FAIL;
        }
        return ApiResponse.OK;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResponse deleteById(Integer id) {
        int delete = crmConfigMapper.deleteById(id);
        if (delete <= 0) {
            return ApiResponse.FAIL;
        }
        return ApiResponse.OK;
    }
}
